package com.geostar.constructionland.analyse.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.geostar.constructionland.analyse.entity.Block;
import com.geostar.constructionland.analyse.entity.HttpResult;
import com.geostar.constructionland.analyse.entity.model.AnalyseModel;
import com.geostar.constructionland.analyse.entity.resulthandler.HandlerResult;
import com.geostar.constructionland.analyse.factory.AnalyseFactory;
import com.geostar.constructionland.analyse.mapper.DlbmVersionMapper;
import com.geostar.constructionland.analyse.mapper.sptalyresult.AlyTypeMappingMapper;
import com.geostar.constructionland.analyse.mapper.sptalyresult.AnalyseVersionMapper;
import com.geostar.constructionland.analyse.service.feignservice.PostAnalyseFeignClient;
import com.geostar.constructionland.common.entity.analyse.AlyTypeMapping;
import com.geostar.constructionland.common.entity.analyse.AnalyseVersion;
import com.geostar.constructionland.common.entity.biz.PieceLandInfo;
import com.geostar.constructionland.common.entity.dkxx.JsydXmdkgx;
import com.geostar.constructionland.common.entity.dlbm.DlbmVersion;
import com.geostar.constructionland.common.entity.response.ServerResponse;
import com.geostar.constructionland.common.global.AnalyseType;
import com.geostar.constructionland.common.mapper.biz.PieceLandInfoMapper;
import com.geostar.constructionland.common.mapper.dkxx.JsydXmdkgxMapper;
import com.geostar.constructionland.common.service.biz.PieceLandInfoService;
import com.geostar.constructionland.common.util.CloneUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author yelll
 * @since 2020-5-28 15:48
 **/
@Service
@Slf4j
public class AnalyseService {
    @Autowired
    PieceLandInfoService pieceLandInfoService;

    @Autowired
    AlyTypeMappingMapper alyTypeMapMapper;
    @Autowired
    HttpAPIService httpAPIService;

    @Autowired
    private PostAnalyseFeignClient postAnalyseFeignClient;

    @Autowired
    ObjectMapper objectMapper;
    @Value("${automatic.deleteFxData}")
    String deleteFxDataUrl;
    @Value("${automatic.yhid}")
    String yhid;
    @Value("${automatic.fxData}")
    String fxDataUrl;
    @Autowired
    AnalyseVersionMapper analyseVersionMapper;
    @Autowired
    JsydXmdkgxMapper jsydXmdkgxMapper;
    @Autowired
    PieceLandInfoMapper pieceLandInfoMapper;
    @Autowired
    DlbmVersionMapper dlbmVersionMapper;

    public HandlerResult analyseJson(AnalyseModel analyseModel) throws Exception{
        /**初始化一些必要数据**/
        /**设置分析ID--分析标示**/
        analyseModel.setAlyId(UUID.randomUUID().toString().replaceAll("-", ""));
        /**设置YWID*/
        analyseModel.setYwid(analyseModel.getAlyId());
        /**查找映射关系**/
        AlyTypeMapping alyTypeMapping = alyTypeMapMapper
                .selectOne(new QueryWrapper<AlyTypeMapping>().eq("analyse_type_original", analyseModel.getFxlx()));
        analyseModel.setFxlxMapped(analyseModel.getFxlx());
        if (alyTypeMapping != null) {
            analyseModel.setFxlxMapped(alyTypeMapping.getAnalyseTypeMapped());
        }

        /**对分析版本进行校验**/
        if(StringUtils.isBlank(analyseModel.getAnalyseVersion())){
            QueryWrapper<AnalyseVersion> aWraper = new QueryWrapper<>();
            List<AnalyseVersion> analyseVersions = analyseVersionMapper.selectList
                    (aWraper.eq("analyse_type",analyseModel.getFxlxMapped()).orderByDesc("version_no"));
            if(analyseVersions.size() == 0 ){
                throw new Exception("没有响应的内容");
            }
            analyseModel.setAnalyseVersion(analyseVersions.get(0).getVersionNo());
        }

        if(analyseModel.getFxlxMapped().equals(AnalyseType.TZHDLGDFX.getCode())){
            /**保存项目地块关系**/
            analyseModel.getBlocks().stream().forEach( block -> {
                String kcdjid = UUID.randomUUID().toString().replace("-","");
                JsydXmdkgx jsydXmdkgx = new JsydXmdkgx();
                jsydXmdkgx.setKcdjId(kcdjid);
                jsydXmdkgx.setYwid(analyseModel.getYwid());
                /**插入项目地块信息数据**/
                jsydXmdkgxMapper.insert(jsydXmdkgx);
                /**插入地块信息**/
                PieceLandInfo pieceLandInfo = new PieceLandInfo();
                pieceLandInfo.setYzGeoJson(block.getGeoJson());
                pieceLandInfo.setKcdjid(kcdjid);
                pieceLandInfo.setJzds("666");
                pieceLandInfo.setDkid(block.getDk_id());
                pieceLandInfoMapper.deleteById(block.getDk_id());
                pieceLandInfoMapper.insert(pieceLandInfo);
            });

            /**由于调整后地类耕地分析 需要使用到平差,所以需要进行面积计算**/
            AnalyseModel analyseMjjs = new AnalyseModel();
            CloneUtil.copyProperties(analyseModel,analyseMjjs);
            analyseMjjs.setFxlx(AnalyseType.MJJS.getCode());
            analyseMjjs.setFxlxMapped(AnalyseType.MJJS.getCode());
            analyseMjjs.setAnalyseVersion("1.0");
            analyseMjjs.setAdjustVersion("1.0");
            AnalyseChain analyseChain_mjjs = AnalyseFactory.getSptAlyParam(analyseMjjs);
            HandlerResult result_mjjs = analyseChain_mjjs.analyse(analyseMjjs.getYwid());
            if(!result_mjjs.isSuccess()){
                return HandlerResult.createByErrorCodeMessage(610,"前置的面积计算分析失败!!!");
            }
        }
        AnalyseChain analyseChain = AnalyseFactory.getSptAlyParam(analyseModel);
        HandlerResult result = analyseChain.analyse(analyseModel.getYwid());

        return result;
    }


    //如果当前没有事务，就新建一个事务，如果已经存在一个事务中，加入到这个事务中
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public HandlerResult analyse(AnalyseModel analyseModel) throws Exception{

        /**兼容内容*/
        String fxlx = analyseModel.getFxlx();
        if(fxlx.contains("Ver")){
            String[] xs = fxlx.split("Ver");
            if(xs.length==2){
                /**重写部分数据*/
                analyseModel.setFxlx(xs[0]);
                analyseModel.setAnalyseVersion(xs[1]);
            }
        }

        /**初始化一些必要数据**/
        /**设置分析ID--分析标示**/
        analyseModel.setAlyId(UUID.randomUUID().toString().replaceAll("-", ""));

        /**查找映射关系**/
        AlyTypeMapping alyTypeMapping = alyTypeMapMapper
                .selectOne(new QueryWrapper<AlyTypeMapping>().eq("analyse_type_original", analyseModel.getFxlx()));
        analyseModel.setFxlxMapped(analyseModel.getFxlx());
        if (alyTypeMapping != null) {
            analyseModel.setFxlxMapped(alyTypeMapping.getAnalyseTypeMapped());
        }

        /**对分析版本进行校验**/
        if(StringUtils.isBlank(analyseModel.getAnalyseVersion())){
         QueryWrapper<AnalyseVersion> aWraper = new QueryWrapper<>();
            List<AnalyseVersion> analyseVersions = analyseVersionMapper.selectList
                    (aWraper.eq("analyse_type",analyseModel.getFxlxMapped()).orderByDesc("version_no"));
            if(analyseVersions.size() == 0 ){
                throw new Exception("没有响应的内容");
            }
            analyseModel.setAnalyseVersion(analyseVersions.get(0).getVersionNo());
            analyseModel.setBlockType(analyseVersions.get(0).getBlockType());
        }

        /**对地类编码版本号进行校验**/
        if(StringUtils.isBlank(analyseModel.getDlbmbbh())){
            LambdaQueryWrapper<DlbmVersion> dlbmWrapper = new LambdaQueryWrapper<>();
            List<DlbmVersion> dlbmVersions = dlbmVersionMapper.selectList(dlbmWrapper.lt(DlbmVersion::getStartTime, new Date())
                    .gt(DlbmVersion::getEndTime, new Date()).eq(DlbmVersion::getStatus, "1").orderByDesc(DlbmVersion::getVersionNumber));
            if(dlbmVersions.size()==0){
                throw new Exception("无对应地类编码版本");
            }
            analyseModel.setDlbmbbh(dlbmVersions.get(0).getVersionNumber());
        }
        /***如果地块信息为空,则需要读取地块信息*/
        if(CollectionUtils.isEmpty(analyseModel.getBlocks())){
            /**设置地块信息**/
            List<PieceLandInfo> landInfos = pieceLandInfoService.getPieceLandInfosByYwid(analyseModel.getYwid());
            List<Block> blocks = new ArrayList<>();
            for (PieceLandInfo landInfo : landInfos) {
                Block block = new Block();
                block.setGeoJson(landInfo.getYzGeoJson());
                block.setDkmj_ys(new BigDecimal(landInfo.getDkmjYs()));
                block.setDkmj(new BigDecimal(landInfo.getDkmj()));
                block.setDk_id(landInfo.getDkid());
                blocks.add(block);
            }
            analyseModel.setBlocks(blocks);
        }
        AnalyseChain analyseChain = AnalyseFactory.getSptAlyParam(analyseModel);
        HandlerResult result = analyseChain.analyse(analyseModel.getYwid());

        // TODO 分析服务后置统计服务 暂时注释
        // 如果分析成功执行后置的统计服务
        if(result.getStatus() == 200) {
            try {
                postAnalyseFeignClient.startPostAnalyse(analyseModel.getFxlx(),analyseModel.getYwid());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    public ServerResponse batchAnalyse(String ywid, String qsnd, String gdnd, String dlnd) throws Exception {
        /**
         * 更新至历史记录表中
         */
        String[] fxlxs = {
                AnalyseType.TZHDLFX.toString(),
                AnalyseType.GHDLFX.toString(),
                AnalyseType.JSYDGZQFX.toString(),
                AnalyseType.YPHXFX.toString(),
                AnalyseType.CSZBYJJBNTFX.toString(),
                AnalyseType.ZPHXFX.toString(),
                AnalyseType.XZQFX.toString()
        };
        Map<String, Object> delParam = new HashMap<>();
        delParam.put("fxlx", StringUtils.join(fxlxs, ","));
        delParam.put("ywid", ywid);
        HttpResult httpResult = httpAPIService.doPost(deleteFxDataUrl, delParam);
        log.info("删除分析类型:{}", httpResult.getBody());
        if (httpResult.getCode() == 200) {
            Map<String, Boolean> map = objectMapper.readValue(httpResult.getBody(), Map.class);
            if (!map.get("data")) {
                return ServerResponse.createByErrorMessage("删除之前的分析数据失败");
            }
            log.info("删除成功!!");
            Map<String, Object> qsMap = new HashMap<>();
            qsMap.put("TZHDLFX", qsnd);

            Map<String, Object> gdndMap = new HashMap<>();
            gdndMap.put("TZHDLFX", gdnd);

            Map<String, Object> dlndMap = new HashMap<>();
            dlndMap.put("TZHDLFX", dlnd);

            Map<String, Object> param = new HashMap<>();
            param.put("sjbs", dlndMap);
            param.put("sjbs2", qsMap);
            param.put("sjbs3", gdndMap);

            param.put("sfsyhcfx", "1");
            param.put("wkid", "4490");
            param.put("yhid", yhid);
            param.put("ywid", ywid);
            param.put("ywlx", "LSPW");
            param.put("ywxl", "LSPW");
            List<Map> errorList = new ArrayList<>();
            for (String fxlx : fxlxs) {
                param.put("fxlx", fxlx);
                HttpResult fxResult = httpAPIService.doPostByJsonParam(fxDataUrl, objectMapper.writeValueAsString(param));
                log.info("内容：{}", fxResult.getBody());
            }
            if (errorList.size() > 0) {
                try {
                    return ServerResponse.createByErrorMessage(objectMapper.writeValueAsString(errorList));
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        return ServerResponse.createBySuccessMessage("分析成功!!");
    }

}
